/*
Copyright (C) 2021-2025 Casa Xu (also Zhiyan Xu) from HIT

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/

//该文件用于隔离各嵌入式操作系统自身特性，提供统一的任务调度API接口（LOS_API）
//当前OS为FreeRTOS，可根据实际任务需求添加uCos、RT-Thread等

#include "LOS_OSAPI.h"

/** @fn LOS_Base_t LOS_Task_Create( LOS_TaskFunc_t  TaskFunc, const char * const TaskName, const uint16_t StackSize, void * const pParameters, LOS_Priority_t Priority, LOS_TaskHandle_t * const pxCreatedTask )
*   @brief OS任务创建函数
*   @param[in] TaskFunc 任务函数
*   @param[in] TaskName 任务名称
*   @param[in] StackSize 堆栈大小
*                         LOS_Task_Stack512B
*                         LOS_Task_Stack1024B
*                         LOS_Task_Stack2048B
*   @param[in] pParameters 传给任务的参数
*   @param[in] Priority 任务优先级，分为如下六个优先级：
*                        LOS_Task_PriorityHighest   
*                        LOS_Task_PriorityHigher    
*                        LOS_Task_PriorityHigh      
*                        LOS_Task_PriorityLow       
*                        LOS_Task_PriorityLower    
*                        LOS_Task_PriorityLowest
*   @param[in] pxCreatedTask 任务句柄，指向任务堆栈    
*                         
*   @return 该函数的返回值为:
*           - pdPASS:  创建成功   
*           - errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY:  创建失败
*/
LOS_Base_t LOS_Task_Create( LOS_TaskFunc_t  TaskFunc, const char * const TaskName, const uint16_t StackSize, void * const pParameters, LOS_Priority_t Priority, LOS_TaskHandle_t * const pxCreatedTask )
{
    return xTaskCreate(TaskFunc,TaskName,StackSize,pParameters,Priority,pxCreatedTask);
}


/** @fn LOS_Task_Delete(LOS_TaskHandle_t xTaskToDelete)
*   @brief OS任务删除函数
*   @param[in] TaskToDelete 要删除的任务句柄
*/
void LOS_Task_Delete(LOS_TaskHandle_t TaskToDelete)
{
    vTaskDelete(TaskToDelete);
}


/** @fn LOS_Task_Delay(const LOS_Tick_t TicksToDelay)
*   @brief OS延时函数
*   @param[in] TicksToDelay 延时时间（ms）
*   该函数会引发任务调度
*/
void LOS_Task_Delay(const LOS_Tick_t TicksToDelay)
{
    vTaskDelay(TicksToDelay);
}


/** @fn LOS_Task_DelayUntil(LOS_Tick_t * const pPreviousWakeTime, const LOS_Tick_t TicksToDelay)
*   @brief OS绝对延时函数，需要满足精确控制周期时请使用该函数
*   @param[in] TicksToDelay 延时时间（ms）
*   @param[in] pPreviousWakeTime 任务开始时间
*   该函数会引发任务调度，需要在第一次进入进程时利用xTaskGetTickCount()函数获取当前时间，并将其返回值的指针给该函数
*/
void LOS_Task_DelayUntil(LOS_Tick_t * const pPreviousWakeTime, const LOS_Tick_t TicksToDelay)
{
    vTaskDelayUntil(pPreviousWakeTime,TicksToDelay);
}


/** @fn LOS_Task_Suspend(LOS_TaskHandle_t TaskToSuspend)
*   @brief OS任务挂起函数
*   @param[in] TaskToSuspend 任务句柄
*/
void LOS_Task_Suspend(LOS_TaskHandle_t TaskToSuspend)
{
    vTaskSuspend(TaskToSuspend);
}


/** @fn LOS_Task_Resume(LOS_TaskHandle_t xTaskToResume)
*   @brief OS任务恢复函数
*   @param[in] TaskToResume 任务句柄
*   将挂起的任务恢复
*/
void LOS_Task_Resume(LOS_TaskHandle_t TaskToResume)
{
    vTaskResume(TaskToResume);
}


/** @fn LOS_Task_SuspendAll()
*   @brief OS挂起所有任务
*   将所有任务挂起（空闲任务除外）
*/
void LOS_Task_SuspendAll()
{
    vTaskSuspendAll();
}


/** @fn LOS_Task_ResumeAll()
*   @brief OS恢复所有任务
*   将所有已挂起任务恢复
*/
void LOS_Task_ResumeAll()
{
    xTaskResumeAll();
}


/** @fn LOS_Task_GetTick()
*   @brief 获取OS当前时间值
*   @return 当前时钟值
*/
LOS_Tick_t LOS_Task_GetTick()
{
    return xTaskGetTickCount();
}


/** @fn LOS_Task_Start(void)
*   @brief OS开启任务调度
*/
void LOS_Task_Start(void)
{
    LOS_Task_Init();
    vTaskStartScheduler();
}

/** @fn LOS_QueueHandle_t LOS_BinSemphr_Create()
*   @brief OS创建二值信号量
*/
LOS_QueueHandle_t LOS_BinSemphr_Create()
{
    return xSemaphoreCreateBinary();
}

/** @fn LOS_BinSemphr_Take(LOS_QueueHandle_t xSemaphore, LOS_Tick_t xBlockTime)
*   @brief OS获取二值信号量
*/
LOS_Base_t LOS_BinSemphr_Take(LOS_QueueHandle_t xSemaphore, LOS_Tick_t xBlockTime)
{
    return xSemaphoreTake(xSemaphore, xBlockTime);
}

LOS_Base_t LOS_BinSemphr_Give(LOS_QueueHandle_t xSemaphore)
{
    return xSemaphoreGive(xSemaphore);
}

/** @fn LOS_Base_t LOS_BinSemphr_GiveFromISR(LOS_QueueHandle_t xSemaphore, LOS_Base_t * const pxHigherPriorityTaskWoken)
*   @brief OS释放二值信号量（中断专用）
*/
LOS_Base_t LOS_BinSemphr_GiveFromISR(LOS_QueueHandle_t xSemaphore, LOS_Base_t * const pxHigherPriorityTaskWoken)
{
    return xSemaphoreGiveFromISR(xSemaphore, pxHigherPriorityTaskWoken);
}
